
package com.wl156.utils;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie2;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class Web {

    private static final String TAG = "DB_Web";

    private static final String HOST = "www.douban.com";

    private static final String BROWSER_COOKIE_NAME = "bid"; // browser_id
                                                             // cookie
    private static final String NET_STORE = "douban_net"; // net
                                                          // SharedPreferences
    private static final String COOKIE_NAME = "cookie_name";
    private static final String COOKIE_VALUE = "cookie_value";
    private static final String COOKIE_DOMAIN = "cookie_domain";
    private static final String COOKIE_PATH = "cookie_path";
    private static final String COOKIE_EXPIRES = "cookie_expires";

    public static boolean isNetworkAvailable(Context context) {

        final ConnectivityManager connectivity = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            final NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) {
                for (int i = 0; i < info.length; i++) {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;

    }

    private final DefaultHttpClient client;
    private final Context context;
    private Cookie cookie;
    private BasicCookieStore cookieStore;

    public Web(Context context) {
        client = HttpClientUtils.getTrustAllHttpClient();
        this.context = context;
        cookie = null;
        cookieStore = new BasicCookieStore();
    }

    public void close() {
        client.getConnectionManager().shutdown();
        cookie = null;
    }

    public DefaultHttpClient getClient() {
        return client;
    }

    private void saveCookie(Cookie cookie, SharedPreferences store) {
        if (cookie != null) {
            SharedPreferences.Editor editor = store.edit();
            editor.putString(COOKIE_NAME, BROWSER_COOKIE_NAME);
            editor.putString(COOKIE_VALUE, cookie.getValue());
            editor.putString(COOKIE_DOMAIN, cookie.getDomain());
            editor.putString(COOKIE_PATH, cookie.getPath());
            final String date = DateFormat.getDateInstance(DateFormat.FULL,
                    Locale.ENGLISH).format(cookie.getExpiryDate());
            Log.v(TAG, "save cookie date=" + date);
            editor.putString(COOKIE_EXPIRES, date);
            editor.commit();
        }
    }

    private Cookie getCookie(SharedPreferences store) {
        final String name = store.getString(COOKIE_NAME, null);
        final String value = store.getString(COOKIE_VALUE, null);
        BasicClientCookie2 c = null;
        if (name != null && value != null) {
            c = new BasicClientCookie2(name, value);
            c.setDomain(store.getString(COOKIE_DOMAIN, ".douban.com"));
            c.setPath(store.getString(COOKIE_PATH, "/"));
            final String date = store.getString(COOKIE_EXPIRES,
                    "Thu, 01-Jan-2012 00:00:00 GMT");
            Log.v(TAG, "get cookie date=" + date);
            try {
                c.setExpiryDate(DateFormat.getDateInstance().parse(date));
            } catch (ParseException e) {
                Log.e(TAG, e.toString());
                c = null;
            }
        }
        return c;
    }

    public Cookie getCookie(String name) {
        final List<Cookie> cookies = client.getCookieStore().getCookies();
        if (!cookies.isEmpty()) {
            for (int i = 0; i < cookies.size(); i++) {
                final Cookie c = cookies.get(i);
                Log.d(TAG, String.format(
                        "cookie name: %s, domain: %s, value: %s.", c.getName(),
                        c.getDomain(), c.getValue()));
                if (c.getName().equalsIgnoreCase(name)) {
                    return c;
                }
            }
        }
        return null;
    }

    private void checkCookie() {
        if (cookie == null) {
            final SharedPreferences store = context.getSharedPreferences(
                    NET_STORE, 0);
            cookie = getCookie(store);
            final Date now = Calendar.getInstance().getTime();
            if (cookie == null || cookie.isExpired(now)) {
                cookie = getCookie(BROWSER_COOKIE_NAME);
                if (cookie != null) {
                    saveCookie(cookie, store);
                    setCookie(cookie);
                }
            } else {
                setCookie(cookie);
            }
        }
    }

    private void setCookie(Cookie c) {
        if (c != null) {
            cookieStore.addCookie(c);
            client.setCookieStore(cookieStore);
        }
    }

    public String getString(String path, String args) throws IOException {
        checkCookie();
        Log.v(TAG, "getString path=" + path + " : " + args);
        HttpGet get = null;
        try {
            get = new HttpGet(new URI("http", null, HOST, 80, path, args, null));
        } catch (URISyntaxException e) {
            Log.e(TAG, e.getMessage());
        }
        HttpResponse response = client.execute(get);
        return EntityUtils.toString(response.getEntity());
    }

    public String getString(String url) throws ClientProtocolException,
            IOException {
        HttpGet get = new HttpGet(url);
        HttpResponse response = client.execute(get);
        return EntityUtils.toString(response.getEntity());
    }

    public byte[] getBinary(String url) throws Exception {
        HttpGet get = new HttpGet(url);
        HttpResponse response = client.execute(get);
        return EntityUtils.toByteArray(response.getEntity());
    }

    public Bitmap getImage(String url) throws Exception {
        final byte[] data = getBinary(url);
        return BitmapFactory.decodeByteArray(data, 0, data.length);
    }

    public String post(String url, List<NameValuePair> nvps) throws IOException {
        HttpPost httpost = new HttpPost(url);
        httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
        HttpResponse response = client.execute(httpost);
        return EntityUtils.toString(response.getEntity());
    }

    public JSONObject getJSON(String path, String args) throws JSONException,
            IOException {
        return new JSONObject(getString(path, args));
    }

    public JSONObject getJSON(String url) throws ClientProtocolException,
            JSONException, IOException {
        return new JSONObject(getString(url));
    }

    public JSONObject postJSON(String url, List<NameValuePair> nvps)
            throws JSONException, IOException {
        return new JSONObject(post(url, nvps));
    }

}
